#include "audio.h"

//==============================================================================DATA
list_s list[256];
int end_list = 0;
int cur_list = 0;
entry_s **ety_buf = NULL;
const char *file_suffix[] = { ".WAV", ".FLAC", ".APE", ".AAC", ".MP2", ".MP3",
			      ".WMA", ".OGG", ".RA", ".RM", ".RMX", "MIDI", 
			      ".AVI", ".VQF", 
			      NULL};
#if 0
typedef enum format{
	UNKNOWF = -1,
	WAV = 0,
	FLAC,
	APE,
	AAC,
	MP2,
	MP3,
	WMA,
	OGG,
	RA,
	RM,
	RMX,
	MIDI,
	AVI,
	VQF
}format_e;
#endif



static int recursive( char *dir  );
static format_e get_suffix( char file[256] );
static entry_s * create_entry_s( char *dir_name, char *file_name, format_e fe );
//==============================================================================FUNCTION
int _list_add( char *dir, char *list_name )
{	
	status.flags |= ADDING;
	status.flags &= ~COMPLETED;
	
	int n = 0, i = 0;
	ety_buf = (entry_s **)malloc( 10000 * sizeof(char *) );
	assert( ety_buf );
	entry_s **ety_buf_temp = ety_buf;
	
	/*create list files*/
	char c[5];
	snprintf( c, 5, "%04u", end_list );
	m3u_open( c, "w+b" );

	/*search audio files*/
	n = recursive( dir );
	ety_buf = ety_buf_temp;
	if( n > 0 ){
		printf( "\ntotal audio files: %d\n" ,n );
		list[end_list].total_entries_number = n;
		list[end_list].dir_name = dir;
		list[end_list].list_name = list_name;
		list[end_list].cur_entry = 0;
		list[end_list].entry_array = (entry_s **)malloc( n * sizeof(char *) );
		memcpy( list[end_list].entry_array, ety_buf, n * sizeof(char *) );
		list[end_list].sequence = (unsigned int *)malloc( n * sizeof(char *) );
		for( i=0 ; i<n ; i++ ) *(list[end_list].sequence + i) = i;
		++end_list;
		list[end_list].dir_name = NULL;
		
		m3u_meta_write( &list[end_list] );
		m3u_close();
	}else{
		m3u_close();		
		m3u_delete( c );
	}


	free( ety_buf );

	status.flags |= COMPLETED;
	return n;	
}

int _list_del( int offset )
{	
	status.flags |= DELING;
	status.flags &= ~COMPLETED;

	/*remove something*/
	memmove( &list[offset], &list[offset+1], sizeof(struct list) * (end_list - offset) );
	char old[5], new[5];
	snprintf( old, 5, "%04u", offset );
 	m3u_delete( old );

	/*rename list files*/
	for( ; offset < end_list ; offset++ ){
		snprintf( new, 5, "%04u", offset );
		snprintf( old, 5, "%04u", offset+1 );
		m3u_rename( old, new );
	}
	end_list--;

	status.flags |= COMPLETED;
	return EXIT_SUCCESS;
}

int lists_read()
{
	status.flags &= ~COMPLETED;
	
	end_list = 0;
	bzero( list, sizeof(list) );
	
	int i=0, j=0;
	char c[5];
	do{
		snprintf( c, 5, "%04u", i );
 		if( m3u_open(c, "rb") != 0 ) break;
		
		/*read lists and entries*/
		m3u_meta_read( &list[i] );
		list[i].entry_array = (entry_s **)malloc( list[i].total_entries_number * sizeof(char *) );
		for( j=0 ; j < list[i].total_entries_number ; j++ ){
			(*(list[i].entry_array + j)) = (entry_s *)malloc( sizeof(struct entry) );
			m3u_info_read( (*(list[i].entry_array + j)) );
		}

		m3u_close();
		end_list++;
		i++;
	}while( 1 );
	m3u_close();

	status.flags |= COMPLETED;
	return end_list;
}

int lists_save()
{
	if( end_list == 0 ) return 0;
	
	int i=0;
	char c[5];
	do{
		snprintf( c, 5, "%04u", i );
 		if( m3u_open(c, "r+b") ) break;
		
		/*save lists and entries*/
		m3u_meta_write( &list[i] );

		m3u_close();
		i++;
	}while(1);
	m3u_close();

	return EXIT_SUCCESS;	
}

//------------------------------------------------------------------------------
static int recursive( char *dir  )
{	
	DIR *d = opendir(dir);
	if( d == NULL ) return 0;
	int total_audio_file = 0;
	struct dirent *di = NULL;
	char *dir_buf = NULL;
	int count = 0;
	format_e fe = UNKNOWF;
	
	while(  (di = readdir(d)) != NULL ){
		
		if( (di->d_type == DT_DIR) && strcmp(di->d_name, ".") && strcmp(di->d_name, "..") ){
			
			dir_buf = (char *)malloc( strlen(dir)+256 );
			assert( dir_buf );
			strcpy( dir_buf, dir );
			strcat( strcat( dir_buf, "/" ), di->d_name );
			
			printf( "\nEnter ::%s\n", dir_buf );
			count = recursive( dir_buf );
			total_audio_file += count;
			printf( "\nReturn::%s\n", dir );
			
			free( dir_buf );
			dir_buf = NULL;
		
		}else if( (di->d_type == DT_REG) && (fe = get_suffix( di->d_name )) != UNKNOWF ){
			
			*ety_buf++ = create_entry_s( dir, di->d_name, fe );
			total_audio_file++;
			
		}else continue;
	}
	
	closedir( d );
	return total_audio_file;
}

static format_e get_suffix( char file[256] )
{
	int n = strlen( file );
	while( (file[--n] != '.') && (n > 0) );
	if( n <= 0 ) return UNKNOWF;

	int i = 0;
	do{
		if( ! strcasecmp( file+n, file_suffix[i] ) ) return (format_e)i;
		i++;
	}while( file_suffix[i] );
	
	return UNKNOWF;
}

static entry_s * create_entry_s( char *dir_name, char *file_name, format_e fe )
{
	char *name_buf = (char *)malloc( strlen(dir_name)+256 );
	assert( name_buf );
	strcpy( name_buf, dir_name );
	strcat( strcat( name_buf, "/" ), file_name );
	
	char *file_name_buf = (char *)malloc( strlen(file_name) - strlen(file_suffix[fe]) + 1 );
	assert( file_name_buf );
	strncpy( file_name_buf, file_name, strlen(file_name) - strlen(file_suffix[fe]) );
	*(file_name_buf + strlen(file_name) - strlen(file_suffix[fe])  ) = '\0';
	printf( "\n\tAudio::%s", file_name_buf );

	entry_s * ety = (entry_s *)malloc( sizeof(struct entry) );
	assert( ety );
	bzero(ety, sizeof(struct entry));
	ety->name = name_buf;
	ety->file_name = file_name_buf;

	struct stat st;
	stat( ety->name, &st );
	ety->size = st.st_size;
	
	printf( "\n\tCreate_Entry :: %s", ety->name );
	printf( ": %d", ety->size );
	ety->format = fe;
	ety->music_buf = NULL;
	ety->music_buf_size = 0;
	ety->music_buf_end = NULL;

	/*parse audio info*/
	parser_solution( ety );

	/*write to m3u*/
	m3u_info_write( ety );

	return ety;
}

